﻿using DapperRepository.DbContext;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Threading.Tasks;
using Dapper.Contrib.Extensions;
using Dapper;

namespace DapperRepository.Repositories
{
    public class Repository : IRepository
    {
        private readonly IContext _context;

        private IDbConnection dbConnection;
        public Repository(IContext context)
        {
            _context = context;
            //dbConnection = this._context.GetDbConnection();
        }

        public Repository(IDbConnection dbConnection)
        {
            this.dbConnection = dbConnection;
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public long Add<T>(T entity) where T : class
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.Insert(entity);
        }
        /// <summary>
        /// 异步添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Task<int> AddAsync<T>(T entity) where T : class
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.InsertAsync(entity);
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Update<T>(T entity) where T : class
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.Update(entity);
        }
        /// <summary>
        /// 异步更新
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Task<bool> UpdateAsync<T>(T entity) where T : class
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.UpdateAsync(entity);
        }
        /// <summary>
        /// 异步执行方法
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parms"></param>
        /// <returns></returns>
        public Task<int> ExecuteAsync(string sql, object parms = null)
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.ExecuteAsync(sql, parms);
        }
        /// <summary>
        /// 执行
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parms"></param>
        /// <param name="commandType"></param>
        /// <returns></returns>
        public int Execute(string sql, object parms = null,CommandType commandType= CommandType.Text)
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.Execute(sql, parms,commandType: commandType);
        }
        /// <summary>
        /// 根据键值查询单个结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T Get<T>(int key) where T : class
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.Get<T>(key);
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Delete<T>(T entity) where T:class
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.Delete(entity);
        }
        /// <summary>
        /// 查询方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="parms"></param>
        /// <param name="commandType"></param>
        /// <returns></returns>
        public dynamic Query(string sql, object parms = null, CommandType commandType = CommandType.Text)
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.Query(sql, parms, commandType: commandType);
        }
        /// <summary>
        /// 查询方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="parms"></param>
        /// <param name="commandType"></param>
        /// <returns></returns>
        public IEnumerable<T> Query<T>(string sql, object parms = null, CommandType commandType = CommandType.Text)
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.Query<T>( sql, parms, commandType: commandType);
        }
        public IEnumerable<TReturn> Query<TFirst, TSecond, TReturn>(string sql,Func<TFirst, TSecond, TReturn> func, object parms = null,string splitOn="", CommandType commandType = CommandType.Text)
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.Query(sql,func, parms,splitOn:splitOn, commandType: commandType);
        }
        /// <summary>
        /// 查询返回第一个结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="parms"></param>
        /// <param name="commandType"></param>
        /// <returns></returns>
        public T QueryFirst<T>(string sql, object parms = null, CommandType commandType = CommandType.Text)
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.QueryFirst<T>(sql, parms, commandType: commandType);
        }

        public dynamic QueryFirst(string sql, object parms = null, CommandType commandType = CommandType.Text)
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.QueryFirst(sql, parms, commandType: commandType);
        }
        /// <summary>
        /// 查询返回第一个结果或默认值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="parms"></param>
        /// <param name="commandType"></param>
        /// <returns></returns>
        public T QueryFirstOrDefault<T>(string sql, object parms = null, CommandType commandType = CommandType.Text)
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.QueryFirstOrDefault<T>(sql, parms, commandType: commandType);
        }

        /// <summary>
        /// 查询返回单个结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="parms"></param>
        /// <param name="commandType"></param>
        /// <returns></returns>
        public T QuerySingle<T>(string sql, object parms = null, CommandType commandType = CommandType.Text)
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.QuerySingle<T>(sql, parms, commandType: commandType);
        }

        /// <summary>
        /// 查询返回单个结果或默认值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="parms"></param>
        /// <param name="commandType"></param>
        /// <returns></returns>
        public T QuerySingleOrDefault<T>(string sql, object parms = null, CommandType commandType = CommandType.Text)
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.QuerySingleOrDefault<T>(sql, parms, commandType: commandType);
        }

        /// <summary>
        /// 查询返回多个结果
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parms"></param>
        /// <param name="commandType"></param>
        /// <returns></returns>
        public SqlMapper.GridReader QueryMultiple(string sql, object parms = null, CommandType commandType = CommandType.Text)
        {
            using (dbConnection = _context.GetDbConnection())
                return dbConnection.QueryMultiple(sql, parms, commandType: commandType);
        }
    }
}
